home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 24
/
Aminet 24 (1998)(GTI - Schatztruhe)[!][Apr 1998].iso
/
Aminet
/
dev
/
c
/
vbcc.lha
/
vbcc
/
statements.c
< prev
next >
Wrap
C/C++ Source or Header
|
1998-02-19
|
30KB
|
880 lines
/* $VER: vbcc (statements.c) V0.4 */
#include "vbc.h"
static char FILE_[]=__FILE__;
int cont_label=0;
int test_assignment(struct Typ *,np);
#define cr()
#ifndef cr
void cr(void)
/* tested Registerbelegung */
{
int i;
for(i=0;i<=MAXR;i++)
if(regs[i]!=regsa[i]) {error(149,regnames[i]);regs[i]=regsa[i];}
}
#endif
void statement(void)
/* bearbeitet ein statement */
{
char *merk;
cr();
killsp();
if(*s=='{'){
enter_block();
if(nesting>0) local_offset[nesting]=local_offset[nesting-1];
compound_statement();leave_block();return;
}
merk=s;
cpbez(buff,0);
if(!strcmp("if",buff)){if_statement();return;}
if(!strcmp("switch",buff)){switch_statement();return;}
if(!strcmp("for",buff)){for_statement();return;}
if(!strcmp("while",buff)){while_statement();return;}
if(!strcmp("do",buff)){do_statement();return;}
if(!strcmp("goto",buff)){goto_statement();return;}
if(!strcmp("continue",buff)){continue_statement();return;}
if(!strcmp("break",buff)){break_statement();return;}
if(!strcmp("return",buff)){return_statement();return;}
if(!strcmp("case",buff)){labeled_statement();return;}
killsp();if(*s==':'){labeled_statement();return;}
/* fehlt Aufruf der anderen statements */
s=merk;
expression_statement();
}
void labeled_statement(void)
/* bearbeitet labeled_statement */
{
struct llist *lp;int def=0;
nocode=0;
if(*s==':'){
s++;
if(!*buff){error(130);return;}
if(!strcmp("default",buff)){def=1;lp=0;} else lp=find_label(buff);
if(lp&&lp->flags&LABELDEFINED){error(131,buff);return;}
if(!lp) lp=add_label(buff);
lp->flags|=LABELDEFINED;
lp->switch_count=0;
if(def){
if(switch_act==0) error(150);
lp->flags|=LABELDEFAULT;
lp->switch_count=switch_act;
}
gen_label(lp->label);
afterlabel=0;
}else{
/* case */
np tree;struct llist *lp;
tree=expression();
killsp();
if(*s==':'){s++;killsp();} else error(70);
if(!switch_count){
error(132);
}else{
if(!tree||!type_expression(tree)){
}else{
if(tree->flags!=CEXPR||tree->sidefx){
error(133);
}else{
if((tree->ntyp->flags&NQ)<CHAR||(tree->ntyp->flags&NQ)>LONG){
error(134);
}else{
lp=add_label(empty);
lp->flags=LABELDEFINED;
lp->switch_count=switch_act;
eval_constn(tree);
if(switch_typ==CHAR) lp->val.vchar=vchar;
if(switch_typ==(UNSIGNED|CHAR)) lp->val.vuchar=vuchar;
if(switch_typ==SHORT) lp->val.vshort=vshort;
if(switch_typ==(UNSIGNED|SHORT)) lp->val.vushort=vushort;
if(switch_typ==INT) lp->val.vint=vint;
if(switch_typ==(UNSIGNED|INT)) lp->val.vuint=vuint;
if(switch_typ==LONG) lp->val.vlong=vlong;
if(switch_typ==(UNSIGNED|LONG)) lp->val.vulong=vulong;
if(switch_typ==POINTER) lp->val.vpointer=vpointer;
gen_label(lp->label);
}
}
}
}
if(tree) free_expression(tree);
}
cr();
killsp();
if(*s!='}') statement();
}
void if_statement(void)
/* bearbeitet if_statement */
{
int ltrue,lfalse,lout,cexpr,cm;char *merk,buff[MAXI];
np tree;struct IC *new;
killsp(); if(*s=='(') s++; else error(151);
killsp();cm=nocode;
tree=expression();
if(!tree) {error(135);
}else{
ltrue=++label;lfalse=++label;
if(type_expression(tree)){
tree=makepointer(tree);
if(!arith(tree->ntyp->flags&NQ)&&(tree->ntyp->flags&NQ)!=POINTER)
{error(136);
}else{
if(tree->flags==ASSIGN) error(164);
gen_IC(tree,ltrue,lfalse);
if(tree->flags==CEXPR){
eval_const(&tree->val,tree->ntyp->flags&NU);
if(zdeqto(vdouble,d2zd(0.0))&&zleqto(vlong,l2zl(0))&&zuleqto(vulong,ul2zul(0UL))) cexpr=2; else cexpr=1;
}else cexpr=0;
if((tree->o.flags&SCRATCH)&&cexpr) free_reg(tree->o.reg);
if(tree->o.flags&&!cexpr){
new=mymalloc(ICS);
new->code=TEST;
new->q1=tree->o;
new->q2.flags=new->z.flags=0;
new->typf=tree->ntyp->flags;
add_IC(new);
new=mymalloc(ICS);
new->code=BEQ;
new->typf=lfalse;
add_IC(new);
}
if(cexpr==2){
new=mymalloc(ICS);
new->code=BRA;
new->typf=lfalse;
add_IC(new);
}
}
}
free_expression(tree);
}
killsp(); if(*s==')') s++; else error(59);
if(cexpr==2) nocode=1;
if(!cexpr&&!tree->o.flags) gen_label(ltrue);
statement();
killsp();
merk=s;
cpbez(buff,0);
if(strcmp("else",buff)) {s=merk;nocode=cm;if(cexpr!=1) gen_label(lfalse);return;}
lout=++label;
if(cexpr!=2){
new=mymalloc(ICS);
new->code=BRA;
new->typf=lout;
add_IC(new);
}
if(cexpr!=1) {nocode=cm;gen_label(lfalse);}
if(cexpr==1) nocode=1; else nocode=cm;
statement();
nocode=cm;
if(cexpr!=2) gen_label(lout);
cr();
}
void switch_statement(void)
/* bearbeitet switch_statement */
{
np tree;int merk_typ,merk_count,merk_break;
struct IC *merk_fic,*merk_lic,*new;struct llist *lp,*l1,*l2;
killsp();
if(*s=='('){s++;killsp();} else error(151);
tree=expression(); killsp();
if(*s==')'){s++;killsp();} else error(59);
merk_typ=switch_typ;merk_count=switch_act;merk_break=break_label;
if(!tree){
error(137);
}else{
if(!type_expression(tree)){
}else{
if((tree->ntyp->flags&NQ)<CHAR||(tree->ntyp->flags&NQ)>LONG){
error(138);
}else{
int m1,m2,m3,def=0,rm,minflag;
zlong l,ml,s;zulong ul,mul,us;
if(tree->flags==ASSIGN) error(164);
m3=break_label=++label;m1=switch_act=++switch_count;
m2=switch_typ=tree->ntyp->flags&NU;
gen_IC(tree,0,0);
if((tree->o.flags&(DREFOBJ|SCRATCH))!=SCRATCH){
new=mymalloc(ICS);
new->code=ASSIGN;
new->q1=tree->o;
new->q2.flags=0;
new->q2.val.vlong=sizetab[m2&NQ];
get_scratch(&new->z,m2,0,0);
new->typf=m2;
tree->o=new->z;
add_IC(new);
}
if((tree->o.flags&(SCRATCH|REG))==(SCRATCH|REG)){
int r=tree->o.reg;
rm=regs[r];
regs[r]=regsa[r];
}
merk_fic=first_ic;merk_lic=last_ic;
first_ic=last_ic=0;
statement();
if((tree->o.flags&(SCRATCH|REG))==(SCRATCH|REG)) regs[tree->o.reg]=rm;
minflag=0;s=l2zl(0L);us=ul2zul(0UL);
for(l1=first_llist;l1;l1=l1->next){
if(l1->switch_count!=m1) continue;
if(l1->flags&LABELDEFAULT){
if(def) error(139);
def=l1->label;
continue;
}
lp=0;minflag&=~1;
for(l2=first_llist;l2;l2=l2->next){
if(l2->switch_count!=m1) continue;
if(l2->flags